home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / sipp / libsipp / cone.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-23  |  7.9 KB  |  265 lines

  1. /*
  2.  * File:  sipp_cone.c
  3.  * 
  4.  * Create a, possibly truncated, cone. Cylinder is a special case
  5.  * of a truncated cone with the same top and bottom radius.
  6.  *
  7.  * Author:  David Jones
  8.  *          djones@awesome.berkeley.edu
  9.  *
  10.  * Adapted for inclusion into the SIPP package by Jonas Yngvesson
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <math.h>
  15.  
  16. #include <sipp.h>
  17. #include <primitives.h>
  18. #include <xalloca.h>
  19.  
  20.  
  21. Object *
  22. sipp_cone(radius_bot, radius_top, length, res, surface, shader, texture)
  23.     double    radius_bot;
  24.     double    radius_top;
  25.     double    length;
  26.     int          res;
  27.     void    * surface;
  28.     Shader  * shader;
  29.     int       texture;
  30. {
  31.     Object  * cone;
  32.     double  * xb;
  33.     double  * yb;
  34.     double  * ub;
  35.     double  * vb;
  36.     double  * xt;
  37.     double  * yt;
  38.     double  * ut;
  39.     double  * vt;
  40.     double    frac;
  41.     double    half_length;
  42.     int       bot_exists;
  43.     int       top_exists;
  44.     int       i;
  45.     
  46.     /*
  47.      * If both top and bottom radii is zero it's a line
  48.      * and can't be rendered.
  49.      */
  50.     if (radius_bot == 0.0 && radius_top == 0.0) {
  51.         return NULL;
  52.     }
  53.  
  54.     if (radius_bot > 0.0) {
  55.         xb = (double *) alloca((res + 1) * sizeof(double));
  56.         yb = (double *) alloca((res + 1) * sizeof(double));
  57.         ub = (double *) alloca((res + 1) * sizeof(double));
  58.         vb = (double *) alloca((res + 1) * sizeof(double));
  59.         bot_exists = 1;
  60.     } else if (radius_bot == 0.0 ){
  61.         bot_exists = 0;
  62.     } else {
  63.         return NULL;
  64.     }
  65.  
  66.     if (radius_top > 0.0) {
  67.         xt = (double *) alloca((res + 1) * sizeof(double));
  68.         yt = (double *) alloca((res + 1) * sizeof(double));
  69.         ut = (double *) alloca((res + 1) * sizeof(double));
  70.         vt = (double *) alloca((res + 1) * sizeof(double));
  71.         top_exists = 1;
  72.     } else if (radius_top == 0.0) {
  73.         top_exists = 0;
  74.     } else {
  75.         return NULL;
  76.     }
  77.     
  78.     half_length = length * 0.5;
  79.  
  80.     /* list of coordinates */
  81.     for (i = 0; i <= res ; ++i) {
  82.         frac = ((double) i) / ((double) res);
  83.         if (bot_exists) {
  84.             xb[i] = radius_bot * cos(frac * 2.0 * M_PI);
  85.             yb[i] = radius_bot * sin(frac * 2.0 * M_PI);
  86.             switch (texture) {
  87.               case NATURAL:
  88.               case CYLINDRICAL:
  89.                 ub[i] = frac;
  90.                 vb[i] = 0.0;
  91.                 break;
  92.  
  93.               case SPHERICAL:
  94.                 ub[i] = frac;
  95.                 vb[i] = atan(-half_length / radius_bot) / M_PI + 0.5;
  96.                 break;
  97.  
  98.               case WORLD:
  99.               default:
  100.                 ub[i] = xb[i];
  101.                 vb[i] = yb[i];
  102.                 break;
  103.             }
  104.         }
  105.         if (top_exists) {
  106.             xt[i] = radius_top * cos(frac * 2.0 * M_PI);
  107.             yt[i] = radius_top * sin(frac * 2.0 * M_PI);
  108.             switch (texture) {
  109.               case NATURAL:
  110.               case CYLINDRICAL:
  111.                 ut[i] = frac;
  112.                 vt[i] = 1.0;
  113.                 break;
  114.  
  115.               case SPHERICAL:
  116.                 ut[i] = frac;
  117.                 vt[i] = atan(half_length / radius_top) / M_PI + 0.5;
  118.                 break;
  119.  
  120.               case WORLD:
  121.               default:
  122.                 ut[i] = xt[i];
  123.                 vt[i] = yt[i];
  124.                 break;
  125.             }
  126.         }
  127.     }
  128.     
  129.     /* empty object */
  130.     cone = object_create();
  131.     
  132.     /* The bottom surface */
  133.     if (bot_exists) {
  134.         for (i = res; i > 0 ; --i) {
  135.             vertex_tx_push(xb[i], yb[i], -half_length,
  136.                            ub[i], vb[i], -half_length);
  137.             vertex_tx_push(xb[i - 1], yb[i - 1], -half_length,
  138.                            ub[i - 1], vb[i - 1], -half_length);
  139.             switch (texture) {
  140.               case NATURAL:
  141.               case CYLINDRICAL:
  142.                 vertex_tx_push(0.0, 0.0, -half_length,
  143.                                ub[i - 1], vb[i - 1], -half_length);
  144.                 vertex_tx_push(0.0, 0.0, -half_length,
  145.                                ub[i], vb[1], -half_length);
  146.                 break;
  147.  
  148.               case SPHERICAL:
  149.                 vertex_tx_push(0.0, 0.0, -half_length,
  150.                                ub[i - 1], 0.0, -half_length);
  151.                 vertex_tx_push(0.0, 0.0, -half_length,
  152.                                ub[i], 0.0, -half_length);
  153.                 break;
  154.  
  155.               case WORLD:
  156.               default:
  157.                 vertex_tx_push(0.0, 0.0, -half_length, 
  158.                                0.0, 0.0, -half_length);
  159.                 break;
  160.             }
  161. /*            vertex_tx_push(0.0, 0.0, -half_length,
  162.                            0.0, 0.0, -half_length);*/
  163.             polygon_push();
  164.         } 
  165.         object_add_surface(cone, surface_create(surface, shader));
  166.     }
  167.     
  168.     /* The top surface */
  169.     if (top_exists) {
  170.         for (i = 0; i < res ; ++i) {
  171.             vertex_tx_push(xt[i], yt[i], half_length,
  172.                            ut[i], vt[i], half_length);
  173.             vertex_tx_push(xt[i + 1], yt[i + 1], half_length,
  174.                            ut[i + 1], vt[i + 1], half_length);
  175.             switch (texture) {
  176.               case NATURAL:
  177.               case CYLINDRICAL:
  178.                 vertex_tx_push(0.0, 0.0, half_length,  
  179.                                ut[i + 1], vt[i + 1], half_length);
  180.                 vertex_tx_push(0.0, 0.0, half_length,  
  181.                                ut[i], vt[i], half_length);
  182.                 break;
  183.  
  184.               case SPHERICAL:
  185.                 vertex_tx_push(0.0, 0.0, half_length,  
  186.                                ut[i + 1], 1.0, half_length);
  187.                 vertex_tx_push(0.0, 0.0, half_length,  
  188.                                ut[i], 1.0, half_length);
  189.                 break;
  190.  
  191.               case WORLD:
  192.               default:
  193.                 vertex_tx_push(0.0, 0.0, half_length,
  194.                                0.0, 0.0, half_length);
  195.                 break;
  196.             }
  197.             polygon_push();
  198.         }
  199.         object_add_surface(cone, surface_create(surface, shader));
  200.     }
  201.     
  202.     /* The side surface */
  203.     for (i = 0; i < res ; ++i) {
  204.         if (top_exists && bot_exists) {
  205.             vertex_tx_push(xb[i], yb[i], -half_length,
  206.                            ub[i], vb[i], -half_length);
  207.             vertex_tx_push(xb[i+1], yb[i+1], -half_length,
  208.                            ub[i+1], vb[i+1], -half_length);
  209.             vertex_tx_push(xt[i+1], yt[i+1], half_length,
  210.                            ut[i+1], vt[i+1], half_length);
  211.             vertex_tx_push(xt[i], yt[i], half_length,
  212.                            ut[i], vt[i], half_length);
  213.         } else if (top_exists) {
  214.             vertex_tx_push(0.0, 0.0, -half_length,
  215.                            0.0, 0.0, -half_length);
  216.             vertex_tx_push(xt[i+1], yt[i+1], half_length,
  217.                            ut[i+1], vt[i+1], half_length);
  218.             vertex_tx_push(xt[i], yt[i], half_length,
  219.                            ut[i], vt[i], half_length);
  220.         } else {
  221.             vertex_tx_push(xb[i], yb[i], -half_length,
  222.                            ub[i], vb[i], -half_length);
  223.             vertex_tx_push(xb[i+1], yb[i+1], -half_length,
  224.                            ub[i+1], vb[i+1], -half_length);
  225.             switch (texture) {
  226.               case NATURAL:
  227.               case CYLINDRICAL:
  228.               case SPHERICAL:
  229.                 vertex_tx_push(0.0, 0.0, half_length,
  230.                                0.0, 1.0, half_length);
  231.                 break;
  232.  
  233.               case WORLD:
  234.               default:
  235.                 vertex_tx_push(0.0, 0.0, half_length,
  236.                                0.0, 0.0, half_length);
  237.                 break;
  238.             }
  239.         }
  240.         polygon_push();
  241.     }
  242.     object_add_surface(cone, surface_create(surface, shader));
  243.     
  244.     return cone;
  245. }
  246.  
  247.  
  248.  
  249. Object *
  250. sipp_cylinder(radius, length, res, surface, shader, texture)
  251.     double    radius;
  252.     double    length;
  253.     int       res;
  254.     void     *surface;
  255.     Shader   *shader;
  256.     int       texture;
  257. {
  258.     Object   *cylinder;
  259.  
  260.     cylinder = sipp_cone(radius, radius, length, res, surface, shader,
  261.                          texture); 
  262.  
  263.     return cylinder;
  264. }
  265.